﻿import { PermissionCheckerService } from '@abp/auth/permission-checker.service';
import { Injectable } from '@angular/core';
import {
    ActivatedRouteSnapshot,
    CanActivate,
    CanActivateChild,
    CanLoad,
    Router,
    RouterStateSnapshot
} from '@angular/router';
import { AppSessionService } from '@shared/common/session/app-session.service';
import { UrlHelper } from '@shared/helpers/UrlHelper';
import { Data, Route } from '@node_modules/@angular/router/src/config';
import { Observable } from '@node_modules/rxjs/internal/Observable';
import { TokenAuthServiceProxy, AuthenticateResultModel } from '@shared/service-proxies/stock-service-proxies';
import { TokenService } from 'abp-ng2-module/dist/src/auth/token.service';
import { UtilsService } from 'abp-ng2-module/dist/src/utils/utils.service';
import { AppConsts } from '@shared/AppConsts';
import { delay } from 'rxjs/operators';

@Injectable()
export class AppRouteGuard implements CanActivate, CanActivateChild, CanLoad {

    flag = 0;
    constructor(
        private _permissionChecker: PermissionCheckerService,
        private _router: Router,
        private _tokenAuthService: TokenAuthServiceProxy,
        private _tokenService: TokenService,
        private _utilsService: UtilsService,
        private _sessionService: AppSessionService
    ) { }

    canActivateInternal(data: Data, state: RouterStateSnapshot): boolean {

        if (UrlHelper.isInstallUrl(location.href)) {
            return true;
        }

        if (!this._sessionService.user) {
            this._router.navigate(['/account/login']);
            return false;
        }

        if (!data || !data['permission']) {
            return true;
        }

        if (this._permissionChecker.isGranted(data['permission'])) {
            return true;
        }

        // this._router.navigate([this.selectBestRoute()]);
        return false;
    }

    async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {

        let isFrame = state && state.root.queryParams['username'];

        if (isFrame) {
            if ((route.data && route.data['useUsername'])) {
                if (!this._sessionService.user || (this._sessionService.user.userName !== state.root.queryParams['username'])) {

                    var result = await this._tokenAuthService
                        .authenticateFrame(state.root.queryParams['username'], state.root.queryParams['systemid'], undefined)
                        .toPromise();

                    console.log(result);

                    if (!result || !result.accessToken) {
                        abp.auth.clearToken();
                        abp.utils.setCookieValue(
                            "enc_auth_token",
                            undefined,
                            undefined,
                            abp.appPath
                        );
                        this._router.navigate(['/account/login']);
                        return false;
                    }



                    let tokenExpireDate = new Date(new Date().getTime() + 1000 * result.expireInSeconds);

                    this._tokenService.setToken(result.accessToken);

                    this._utilsService.setCookieValue(
                        AppConsts.authorization.encrptedAuthTokenName,
                        result.encryptedAccessToken,
                        tokenExpireDate,
                        abp.appPath
                    );
                }
            }

            return true;
        }


        return this.canActivateInternal(route.data, state);
    }

    async canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
        var isFrame = state && state.root.queryParams['username'];

        if (isFrame) return true;

        return await this.canActivate(route, state);
    }

    canLoad(route: Route): Observable<boolean> | Promise<boolean> | boolean {
        return this.canActivateInternal(route.data, null);
    }

    selectBestRoute(): string {
        if (!this._sessionService.user) {
            return '/account/login';
        }
        if (this._permissionChecker.isGranted('Pages.Tenant.LeaderDashboard')) {
            return '/app/main/leaderdashboard';
        }
        if (this._permissionChecker.isGranted('Pages.Administration.Host.Dashboard')) {
            return '/app/admin/hostDashboard';
        }

        if (this._permissionChecker.isGranted('Pages.Tenant.Dashboard')) {
            return '/app/main/dashboard';
        }

        if (this._permissionChecker.isGranted('Pages.Tenants')) {
            return '/app/admin/tenants';
        }

        if (this._permissionChecker.isGranted('Pages.Administration.Users')) {
            return '/app/admin/users';
        }

        return '/app/notifications';
    }


}
